package com.ys.p5TreeMap了解;

import java.util.Comparator;
import java.util.Iterator;
import java.util.Map;
import java.util.TreeMap;

/**
 * 描述: TreeMap测试
 * TreeMap 的底层就是红黑二叉树,因此“增、删、改和查”的效率都非常高，并且使有序的。
 * 因为 TreeMap 源码 调用了比较器(无参构造方法,内部比较器,有参,外部比较器),来做自然传入的比较,做到有序.
 * <p>
 * TreeMap是Map接口的实现类，也就意味着TreeMap可以使用Map中提供的方法。
 *
 * @author CodeYang
 * @version 2020/12/28 19:22
 */
public class TreeMap测试 {
    public static void main(String[] args) {
        // 1 无参构造 TreeMap
        TreeMap<String, Integer> treeMap = new TreeMap<>();
        // 2-1 使用Java自带的类做为key 都实现了Comparable<E> 内部都实现了 compareTo 内部比较器这个方法
        treeMap.put("1", 1);
        treeMap.put("3", 3);
        treeMap.put("2", 212);
        for (Map.Entry<String, Integer> entry : treeMap.entrySet()) {
            System.out.println(entry);
        }
        /**
         * 结果: 排序了
         * 1=1
         * 2=212
         * 3=3
         *  因为,put 时会判断后如果 没有传入外部比较器,那么就使用内部比较器来做比较后,做排序.
         *  跟插入顺序无关,跟我们的key 值大小有关.
         *  这里调用了的就是String.compareTo 的方法,默认是 升序排序
         */

        // 2-2 传入key为自定义类
        // 如果 把 自定义类作为key, 不实现 Comparable<E>--compareTo方法  会报(ClassCastException)类型转换异常,因为put里
        // 没有传入有参的 TreeMap 默认有一步转换 为  Comparator<? super K> cpr = comparator; 比较器
        // 在调用 内部比较器的   cmp = cpr.compare(key, t.key); 方法来进行比较
        // 升序小的放前面,大的放后面.
        TreeMap<Student, Integer> treeMap2 = new TreeMap<>();

        treeMap2.put(new Student("03", 19), 2);
        treeMap2.put(new Student("02", 28), 3);
        treeMap2.put(new Student("01", 18), 1);

        Iterator<Map.Entry<Student, Integer>> iterator = treeMap2.entrySet().iterator();
        while (iterator.hasNext()) {
            System.out.println(iterator.next());
        }
        // 2 有参构造TreeMap 传入外部比较器
        System.out.println("---------------");

        TreeMap<Student, Integer> treeMap3 = new TreeMap<>(new Comparator<Student>() {
            /**
             *  名字相同时 按照年龄降序输出
             * @param o1
             * @param o2
             * @return
             */
            @Override
            public int compare(Student o1, Student o2) {

                // 02.compareTo(o1) 就是降序
               // int i = o2.getName().compareTo(o1.getName());
               // 01.compareTo(o2) 就是升序
               // int i=o1.getName().compareTo(o2.getName());

               // 名字相同时 按照年龄降序输出 否则按年龄升序输出
                if (o1.getName().equals(o2.getName())){
                    return o2.getAge() - o1.getAge();
                }
                return o1.getAge() - o2.getAge();
            }
        });
        // 这里没有重写hashcode 与 eqluas 方法,所以 姓名 与 age 重复 会当成不同的key
        // 正常情况下 key为自定义类时必须重写,达到key值唯一的效果
        treeMap3.put(new Student("03",19),2);
        treeMap3.put(new Student("02",28),3);
        treeMap3.put(new Student("01",88),1);
        treeMap3.put(new Student("01",50),1);
        treeMap3.put(new Student("05",9),99);
        /**
         * // 姓名不同时 按 age 升序排序
         * Student{name='05', age=9}=99
         * Student{name='03', age=19}=2
         * Student{name='02', age=28}=3
         * // 姓名相同时 按age降序排序
         * Student{name='01', age=88}=1
         * Student{name='01', age=50}=1
         */

        Iterator<Map.Entry<Student, Integer>> iterator3 = treeMap3.entrySet().iterator();
        while (iterator3.hasNext()){
            System.out.println(iterator3.next());
        }
    }


}
